#include <stdio.h>
#include "label.h"
#include "register.h"
#include "AAT.h"
#include "MachineDependent.h"



/*
AATstatement Allocate(Label blockName, int dataSize){
	return AATMemoryAllocation(blockName, dataSize);

}
*/
AATstatement Allocate(AATexpressionList blocks){
	return AATProcedureCall("allocateMemory", blocks);
}

AATexpression MemoryAllocation(Label blockName, int dataSize){
	return AATMemoryAllocation(
				blockName, 
				AATConstant(dataSize)
			);
}

AATexpression ConstantBoolExpression(int value){
  return AATConstant(value);
}

AATexpression ConstantIntExpression(int value){
  return AATConstant(value);
}

AATexpression OperatorExpression(AATexpression left, AATexpression right, AAToperator operator){
  return AATOperator(left, right, operator);
}

AATstatement AssignmentStatement(AATexpression lhs, AATexpression rhs){
	return AATMove(lhs, rhs);
}


AATexpression BooleanVariable(Label blockName, int offset){
	AATexpression memOffset = AATConstant(offset);
	return AATMemory(blockName,memOffset);
}

AATexpression IntegerVariable(Label blockName,int offset){
	AATexpression memOffset = AATConstant(offset);
	return AATMemory(blockName,memOffset);
}

AATexpression ArrayVariable(Label blockName, int baseOffset, AATexpression leftArrayIndex, AATexpression index, int elementSize){
	AATexpression absIndex = AATOperator( index, leftArrayIndex, AAT_MINUS );
	AATexpression indexShift = AATOperator( absIndex, AATConstant(elementSize), AAT_MULTIPLY );
	return AATMemory(	
						blockName,
						AATOperator(
										AATConstant(baseOffset),
										indexShift,
										AAT_PLUS
									)
					);

}

AATexpression RecordVariable(Label blockName, int baseOffset, int internalVariableOffset){
	return AATMemory(
						blockName,
						AATOperator(
										AATConstant(baseOffset),
										AATConstant(internalVariableOffset),
										AAT_PLUS
									)
					);
}

AATstatement SequentialStatement(AATstatement first, AATstatement second){
	return AATSequential(first, second);

}

AATstatement EmptyStatement(){
	return AATEmpty();

}

AATstatement IfStatement(AATexpression test, AATstatement ifbody, AATstatement elsebody){
	Label elseLabel = NewLabel();
	Label endIfLabel = NewLabel();
	AATstatement endIfStatementLabel = AATLabel( endIfLabel );
	AATstatement elseStatementLabel = AATLabel( elseLabel );

	AATexpression testNegative = AATConstant(0);
	AATexpression testCheck = AATOperator(testNegative, test, AAT_EQ);
	
	AATstatement elseJump = AATConditionalJump(testCheck, elseLabel);	
	
	AATstatement ifSeq = AATSequential( elseJump, 
					AATSequential( ifbody,
						AATSequential( AATJump(endIfLabel),
							AATSequential( elseStatementLabel,
								AATSequential(elsebody, endIfStatementLabel)
							)
						)
					)
				);				
	return ifSeq;

}

AATstatement CallStatement(Label name, AATexpressionList actuals){
	return AATProcedureCall(name, actuals);
}


AATstatement ProcedureDefinition(AATstatement body, int argsSize ,Label start, Label end){
	return AATProcedureDefinition(body, argsSize, start, end);

}

AATstatement CallPrintStatement(AATexpression exp){
	 AATexpressionList actuals = AATExpressionList(exp, NULL);
	return AATProcedureCall("printAtomVariable", actuals);
}

AATstatement CallPrintLineStatement(){
	return AATProcedureCall("printLine", NULL);

}

AATstatement WhileDoStatement(AATexpression test, AATstatement dowhilebody){
	Label whileBeginLabel = NewLabel();
	Label whileEndLabel = NewLabel();

	AATstatement whileBeginStatementLabel = AATLabel( whileBeginLabel );
	AATstatement whileEndStatementLabel = AATLabel( whileEndLabel );

	AATexpression testNegative = AATConstant(0);
	AATexpression testCheck = AATOperator(testNegative, test, AAT_EQ);

	AATstatement whileEndJump = AATConditionalJump(testCheck, whileEndLabel);

	AATstatement whileSeq = AATSequential( whileBeginStatementLabel,
						AATSequential( whileEndJump, 
							AATSequential( dowhilebody, 
								AATSequential( AATJump(whileBeginLabel), whileEndStatementLabel) 
							)
						)
				);
	return whileSeq;

}

